import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { EvaluationDataModel } from './evaluation-data.model';
import { EvaluationDataBatchDto } from '@/module/evaluation-data/evaluation-data.dto';
import { BooleanNumber, EvaluationProjectType } from 'common/utils/data';
import { EvaluationProjectModel } from "@/module/evaluation-project/evaluation-project.model";
import { csvStrToDataSet } from 'common/utils/utils';
import { EvaluationDataBatchResult } from './evaluation-data.result';
import { BizFailedException } from '@/common/biz-failed/biz-failed.exception';
import { BizFailedCodeEnum } from '@/common/biz-failed/biz-failed.enum';

@Injectable()
export class EvaluationDataService {
  constructor(
    @InjectRepository(EvaluationDataModel)
    private readonly evaluationDataModelRepository: Repository<EvaluationDataModel>,
    @InjectRepository(EvaluationProjectModel)
    private readonly evaluationProjectModelRepository: Repository<EvaluationProjectModel>,
  ) {
    // this.isCompensatingDigitalImgRedisClient = redisService.getClient(RedisNamespace.is_compensating_digital_img);
  }


  async batch(body: EvaluationDataBatchDto): Promise<EvaluationDataBatchResult[]>{
    const res = await Promise.all(body.list.map(item=>{
      return this.evaluationDataModelRepository.createQueryBuilder('evaluationData')
      .leftJoinAndSelect('evaluationData.evaluation', 'evaluation')
      .leftJoinAndSelect('evaluation.brand', 'brand')
      .select([
        'evaluationData.uuid',
        'evaluationData.data',
        'evaluationData.name',
        'evaluationData.group',
        'evaluationData.img',
        'evaluationData.json',
        'evaluationData.evaluationUuid',
        'evaluation.uuid',
        'evaluation.title',
        'brand.uuid',
        'brand.title',
      ])
      .where('evaluationData.evaluationUuid = :evaluationUuid', { evaluationUuid: item.evaluationUuid })
      .andWhere('evaluationData.group = :group', { group: item.group })
      .andWhere('evaluationData.projectUuid = :projectUuid', { projectUuid: item.projectUuid })
      .getOne();
    }));
    if(res.some(item=>!item)){
      throw new BizFailedException(BizFailedCodeEnum.EVALUATION_DATA_LIST_NOT_ALL_HAS_FREQ);
    }
    return res.map(item=>{
      return {
        ...item!,
        dataSet: item!.data ? this.getEvaluationDataSet(item!.data) : [],
      }
    })
  }

  getEvaluationDataSet(sourceData: string) {
    return csvStrToDataSet(sourceData)
  }

  // 查询文章时，处理数据文章的evaluationDatas字段
  getEvaluationDatasBySourceEvaluationDataModel(datas: EvaluationDataModel[], projects?: EvaluationProjectModel[]) {
    // 数据项重新排序
    let evaluationDatasRes = datas.sort((a, b) => a.sort - b.sort);

    // 如果传了这个，那么以外面传的为准给datas的project字段赋值
    if(projects){
      evaluationDatasRes.forEach(item=>{
        item.project = projects.find(project=>project.uuid === item.projectUuid)!;
      });
    }

    // 分组
    let groupRes: {
      project: Pick<EvaluationProjectModel, 'rule'|'name'|'sort'|'type'|'desc'|'uuid'|'code'> ;
      projectUuid: string;
      children: (Pick<EvaluationDataModel, 'name'|'group'|'desc'|'img'|'json'|'defaultShow'> & {dataSet: string[][]})[];
      uuid: string;
    }[] = [];
    evaluationDatasRes.forEach((item) => {
      const { name, data, desc, img, json, defaultShow, ...restItem } = item;
      if (
        groupRes.every(
          (groupDataItem) => groupDataItem.projectUuid !== item.projectUuid,
        )
      ) {
        groupRes.push({
          ...restItem,
          children: [],
        });
      }
    });
    // 根据测试项类型排序排序
    groupRes = groupRes.sort((a, b) => a.project.sort - b.project.sort);
    evaluationDatasRes.forEach((evaluationDataItem) => {
      const currentGroupData = groupRes.find(
        (item) => item.projectUuid === evaluationDataItem.projectUuid,
      )!;
      currentGroupData.children.push({
        name: evaluationDataItem.name,
        dataSet: this.getEvaluationDataSet(
          evaluationDataItem.data,
        ),
        desc: evaluationDataItem.desc,
        img: evaluationDataItem.img,
        group: evaluationDataItem.group,
        json: evaluationDataItem.json,
        defaultShow: evaluationDataItem.defaultShow,
      });
    });
    return groupRes;
  }

  getEvaluationDataGroups(datas: EvaluationDataModel[]){
    return Array.from(new Set(datas.filter(item=>item.group).map(item=>item.group)))
  }
}
